import grails.test.*
import org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
import groovy.mock.interceptor.MockFor
import java.awt.image.BufferedImage

class ImageTagLibTests extends GroovyTestCase {
	def imageTagLib;
	def testImageName;
	def testFaviconName;

	def testImageTag;
	def testImageTagWithName;
	def testImageTagWithEmptyName;
	def testImageTagWithDescription;
	def testImageTagWithEmptyDescription;
	def testImageTagWithNameAndDescription;
	def testImageTagWithEmptyNameAndDescription;

	def testFaviconTag;

	void setUp(){
		imageTagLib = new ImageTagLib()
		testImageName = "test.png"
		testFaviconName = "test.ico"

		testImageTag = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="${testImageName}" """ +
			"""alt="${testImageName}" title="${testImageName}" />""";

		testImageTagWithName = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="Test" """ +
			"""alt="${testImageName}" title="${testImageName}" />""";

		testImageTagWithEmptyName = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="" """ +
			"""alt="${testImageName}" title="${testImageName}" />""";

		testImageTagWithDescription = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="${testImageName}" """ +
			"""alt="Test" title="Test" />""";

		testImageTagWithEmptyDescription = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="${testImageName}" """ +
			"""alt="" title="" />""";

		testImageTagWithNameAndDescription = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="Test" """ +
			"""alt="Test" title="Test" />""";

		testImageTagWithEmptyNameAndDescription = """<img src="/images/${testImageName}" """ +
			"""width="10" height="20" name="" alt="" title="" />""";

		testFaviconTag = """<link rel="shortcut icon" href="/images/${testFaviconName}" """ +
			"""type="image/x-icon" />""";
	}

	void testImage_Source() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
				assertEquals("Unexpected image tag returned!", testImageTag,
						imageTagLib.image([src: "test.png"]));
		}
	}

	void testImage_NullSource() {
		try {
			imageTagLib.image();
			fail("Tag [image] should throw GrailsTagException when [src] is NULL!");
		} catch (GrailsTagException GTE) {
			assertEquals("Unexpected GrailsTagException was thrown!",
					"Tag [image] is missing required attribute [src]", GTE.getMessage());
		}
	}

	void testImage_EmptySource() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO)
		mockImageFile.demand.read { a -> null }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", "",
					imageTagLib.image([src: ""]));
		}
	}

	void testImage_InvalidSource() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO)
		mockImageFile.demand.read { a -> null }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", "",
					imageTagLib.image([src: "test.png"]));
		}
	}

	void testImage_Name() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithName,
					imageTagLib.image([src: "test.png", name: "Test"]));
		}
	}

	void testImage_EmptyName() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithEmptyName,
					imageTagLib.image([src: "test.png", name: ""]));
		}
	}

	void testImage_Description() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithDescription,
					imageTagLib.image([src: "test.png", description: "Test"]));
		}
	}

	void testImage_EmptyDescription() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithEmptyDescription,
					imageTagLib.image([src: "test.png", description: ""]));
		}
	}

	void testImage_NameAndDescription() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithNameAndDescription,
					imageTagLib.image([src: "test.png", name: "Test", description: "Test"]));
		}
	}

	void testImage_EmptyNameAndDescription() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> new BufferedImage(10, 20, BufferedImage.TYPE_INT_RGB) }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", testImageTagWithEmptyNameAndDescription,
					imageTagLib.image([src: "test.png", name: "", description: ""]));
		}
	}

	void testImage_NoSourceNameAndDescription() {
		try {
			imageTagLib.image([name: "Test", description: "Test"]);
			fail("Tag [image] should throw GrailsTagException when [src] is NULL!");
		} catch (GrailsTagException GTE) {
			assertEquals("Unexpected GrailsTagException was thrown!",
					"Tag [image] is missing required attribute [src]", GTE.getMessage());
		}
	}

	void testImage_EmptySourceNameAndDescription() {
		def mockImageFile = new MockFor(javax.imageio.ImageIO.class)
		mockImageFile.demand.read { arg -> null }
		mockImageFile.use {
			assertEquals("Unexpected image tag returned!", "",
					imageTagLib.image([src: "", name: "Test", description: "Test"]));
		}
	}

	void testFavicon() {
		def mockFaviconFile = new MockFor(java.io.File.class)
		mockFaviconFile.demand.exists { -> true }
		mockFaviconFile.demand.isFile { -> true }
		mockFaviconFile.use {
			assertEquals("Unexpected favicon tag returned!", testFaviconTag,
					imageTagLib.favicon([src: "test.ico"]));
		}
	}

	void testFavicon_NoSource() {
		try {
			imageTagLib.favicon();
			fail("Tag [favicon] should throw GrailsTagException when [src] is NULL!");
		} catch (GrailsTagException GTE) {
			assertEquals("Unexpected GrailsTagException was thrown!",
					"Tag [favicon] is missing required attribute [src]", GTE.getMessage());
		}
	}

	void testFavicon_EmptySource() {
		def mockFaviconFile = new MockFor(java.io.File.class)
		mockFaviconFile.demand.exists { -> false }
		mockFaviconFile.use {
			assertEquals("Unexpected favicon tag returned!", "",
					imageTagLib.favicon([src: ""]));
		}
	}

	void testFavicon_InvalidSource() {
		def mockFaviconFile = new MockFor(java.io.File.class)
		mockFaviconFile.demand.exists { -> false }
		mockFaviconFile.use {
			assertEquals("Unexpected favicon tag returned!", "",
					imageTagLib.favicon([src: "test.ico"]));
		}
	}

	void testFavicon_InvalidSource_IsDirectory() {
		def mockFaviconFile = new MockFor(java.io.File.class)
		mockFaviconFile.demand.exists { -> true }
		mockFaviconFile.demand.isFile { -> false }
		mockFaviconFile.use {
			assertEquals("Unexpected favicon tag returned!", "",
					imageTagLib.favicon([src: "test.ico"]));
		}
	}
}
